/******************************************************************
***
***
***				FREE WINDOWLESS FLASH CONTROL
***
***					   by Makarov Igor
***
***		for questions and remarks mailto: mak_july@list.ru
***
***
*******************************************************************/
// FlashWnd.h: interface for the CFlashWnd class.
//
//////////////////////////////////////////////////////////////////////

#if !defined(AFX_FLASHWND_H__D74EA89B_5D79_4D87_8BB9_4DB90A5FE8FC__INCLUDED_)
#define AFX_FLASHWND_H__D74EA89B_5D79_4D87_8BB9_4DB90A5FE8FC__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

//#import "c:\\Flash.ocx" named_guids no_auto_exclude
#import "PROGID:ShockwaveFlash.ShockwaveFlash"  named_guids no_auto_exclude
#include <sync/bflock.h>
#include "CallFlashEncode.h"
#include "../../ImageHelper/IImageHelper.h"

typedef ShockwaveFlashObjects::IShockwaveFlash			IAdobeShockwaveFlash;
typedef ShockwaveFlashObjects::_IShockwaveFlashEvents	IAdobeShockwaveFlashEvent;
typedef ShockwaveFlashObjects::IServiceProvider			IAdobeServiceProvider;
typedef ShockwaveFlashObjects::ShockwaveFlash			CShockwaveFlash;
namespace BFFlash
{
	class IFlashContainerEvent
	{
	public:
		virtual HRESULT OnDraw() = 0;
		virtual HRESULT OnChangeImageHelper(BFImageHelper::IImageHelper * pImgHelper) =0 ;
		virtual HRESULT OnFSCommand(LPCWSTR pCmd,LPCWSTR pArgs) =0;
		virtual HRESULT OnFlashCall(LPCWSTR request,VARIANT * pRes) = 0;
	};

	class IFlashContainer
	{
	public:
		virtual ~IFlashContainer(){};
		virtual HRESULT pushArgument(VARIANT * varArgument) = 0;
		virtual HRESULT callFunction(LPCWSTR pFunName,VARIANT * result) = 0;
		virtual HRESULT destroy() = 0;
		virtual HRESULT setSize(LONG nWidth,LONG nHeight) = 0;
		virtual LONG	getWidth() = 0;
		virtual LONG	getHeight() = 0;
		virtual HRESULT handleMessage(UINT msg,WPARAM wParam,LPARAM lParam,LRESULT * lResult) = 0;
		virtual HRESULT setReturnValue( LPCWSTR lpsz ) = 0;
	};
	class CFlashContainer : public CUnknown,
		public IOleClientSite,
		public IOleInPlaceSiteWindowless,
		public IOleInPlaceFrame,
		public IStorage,
		public IAdobeShockwaveFlashEvent,
		public IFlashContainer
	{
	public:
		CComPtr<IAdobeShockwaveFlash>			m_spFlashControl;
		CComPtr<IOleObject>						m_spOleObject;
		CComPtr<IViewObjectEx>					m_spViewObjectEx;
		CComPtr<IOleInPlaceObject>				m_spInPlaceObject;
		CComPtr<IOleInPlaceObjectWindowless>	m_spInPlaceObjectWindowless;
		CComPtr<IConnectionPointContainer>		m_spConnPoitContainer;
		CComPtr<IConnectionPoint>				m_spConnPoint;

		CBFBaseObjPtr<BFImageHelper::IImageFactory>			m_pImageFactory;
		BOOL				m_bVisible;
		HWND				m_hWndParent;
		BOOL				m_bTransparent;
		DWORD				m_dwConnPointCookie;

		IFlashContainerEvent *					m_pContainerEvent;
		CBFCritSec			m_CSRect;
		RECT				m_rcPos;
		CBFBaseObjPtr<BFImageHelper::IImageHelper>			m_spBackImgHelper;
		CBFBaseObjPtr<BFImageHelper::IImageHelper>			m_spWhiteImgHelper;

		DECLARE_IUNKNOWN;
		virtual HRESULT STDMETHODCALLTYPE NonDelegatingQueryInterface(REFIID riid, void** ppv);
		CFlashContainer(LPCWSTR pFixSwfFile,HWND hWndParent,BOOL bTrasnparent,LONG nWidth,LONG nHeight,BFImageHelper::IImageFactory * pImgFactory,IFlashContainerEvent * pEvent,HRESULT * phr);
		virtual ~CFlashContainer();
	private:
		//IOleClientSite
		virtual HRESULT STDMETHODCALLTYPE SaveObject() { return E_NOTIMPL; }
		virtual HRESULT STDMETHODCALLTYPE GetMoniker(DWORD dwAssign, DWORD dwWhichMoniker, IMoniker ** ppmk){ return E_NOTIMPL; }
		virtual HRESULT STDMETHODCALLTYPE GetContainer(LPOLECONTAINER * ppContainer){*ppContainer = NULL;return E_NOINTERFACE;}
		virtual HRESULT STDMETHODCALLTYPE ShowObject(){return S_OK;}
		virtual HRESULT STDMETHODCALLTYPE OnShowWindow(BOOL fShow){return E_NOTIMPL;}
		virtual HRESULT STDMETHODCALLTYPE RequestNewObjectLayout(){return E_NOTIMPL;}

		//IOleInPlaceSite
		virtual HRESULT STDMETHODCALLTYPE GetWindow(HWND * lphwnd);
		virtual HRESULT STDMETHODCALLTYPE ContextSensitiveHelp(BOOL fEnterMode){ return E_NOTIMPL; }
		virtual HRESULT STDMETHODCALLTYPE CanInPlaceActivate(){return S_OK;}
		virtual HRESULT STDMETHODCALLTYPE OnInPlaceActivate(){ return S_OK; }
		virtual HRESULT STDMETHODCALLTYPE OnUIActivate(){ return S_OK; }

		virtual HRESULT STDMETHODCALLTYPE GetWindowContext(LPOLEINPLACEFRAME * lplpFrame,LPOLEINPLACEUIWINDOW * lplpDoc,LPRECT lprcPosRect,LPRECT lprcClipRect,LPOLEINPLACEFRAMEINFO lpFrameInfo);
		virtual HRESULT STDMETHODCALLTYPE Scroll(SIZE scrollExtent){return E_NOTIMPL;}
		virtual HRESULT STDMETHODCALLTYPE OnUIDeactivate(BOOL fUndoable){return S_OK;}
		virtual HRESULT STDMETHODCALLTYPE OnInPlaceDeactivate(){return S_OK;}
		virtual HRESULT STDMETHODCALLTYPE DiscardUndoState(){return E_NOTIMPL;}
		virtual HRESULT STDMETHODCALLTYPE DeactivateAndUndo(){return E_NOTIMPL;}
		virtual HRESULT STDMETHODCALLTYPE OnPosRectChange(LPCRECT lprcPosRect){return S_OK;}

		//IOleInPlaceSiteEx
		virtual HRESULT STDMETHODCALLTYPE OnInPlaceActivateEx(BOOL  *pfNoRedraw, DWORD dwFlags);
		virtual HRESULT STDMETHODCALLTYPE OnInPlaceDeactivateEx(BOOL fNoRedraw){return S_FALSE;}
		virtual HRESULT STDMETHODCALLTYPE RequestUIActivate(void){return S_FALSE;}

		//IOleInPlaceSiteWindowless
		virtual HRESULT STDMETHODCALLTYPE CanWindowlessActivate( void){return S_OK;}
		virtual HRESULT STDMETHODCALLTYPE GetCapture( void){return S_FALSE;}
		virtual HRESULT STDMETHODCALLTYPE SetCapture( BOOL fCapture){return S_FALSE;}
		virtual HRESULT STDMETHODCALLTYPE GetFocus( void){return S_OK;}
		virtual HRESULT STDMETHODCALLTYPE SetFocus( BOOL fFocus){return S_OK;}
		virtual HRESULT STDMETHODCALLTYPE GetDC(LPCRECT pRect,DWORD grfFlags,HDC *phDC){return S_FALSE;}
		virtual HRESULT STDMETHODCALLTYPE ReleaseDC( HDC hDC){return S_FALSE;}
		virtual HRESULT STDMETHODCALLTYPE InvalidateRect( LPCRECT pRect,BOOL fErase);
		virtual HRESULT STDMETHODCALLTYPE InvalidateRgn( HRGN hRGN,BOOL fErase){return S_OK;} 
		virtual HRESULT STDMETHODCALLTYPE ScrollRect( INT dx,INT dy,LPCRECT pRectScroll,LPCRECT pRectClip){return E_NOTIMPL;}
		virtual HRESULT STDMETHODCALLTYPE AdjustRect( LPRECT prc){return S_FALSE;}
		virtual HRESULT STDMETHODCALLTYPE OnDefWindowMessage( UINT msg,WPARAM wParam,LPARAM lParam,LRESULT *plResult){return S_FALSE;}

		//IOleInPlaceFrame
		virtual HRESULT STDMETHODCALLTYPE GetBorder(LPRECT lprectBorder){return E_NOTIMPL;}
		virtual HRESULT STDMETHODCALLTYPE RequestBorderSpace(LPCBORDERWIDTHS pborderwidths){return E_NOTIMPL;}
		virtual HRESULT STDMETHODCALLTYPE SetBorderSpace(LPCBORDERWIDTHS pborderwidths){return E_NOTIMPL;}
		virtual HRESULT STDMETHODCALLTYPE SetActiveObject(IOleInPlaceActiveObject *pActiveObject, LPCOLESTR pszObjName){return S_FALSE;}
		virtual HRESULT STDMETHODCALLTYPE InsertMenus(HMENU hmenuShared, LPOLEMENUGROUPWIDTHS lpMenuWidths){return E_NOTIMPL;}
		virtual HRESULT STDMETHODCALLTYPE SetMenu(HMENU hmenuShared, HOLEMENU holemenu, HWND hwndActiveObject){return S_OK;}
		virtual HRESULT STDMETHODCALLTYPE RemoveMenus(HMENU hmenuShared){return E_NOTIMPL;}
		virtual HRESULT STDMETHODCALLTYPE SetStatusText(LPCOLESTR pszStatusText){return S_OK;}
		virtual HRESULT STDMETHODCALLTYPE EnableModeless(BOOL fEnable){return S_OK;}
		virtual HRESULT STDMETHODCALLTYPE TranslateAccelerator(LPMSG lpmsg, WORD wID){return E_NOTIMPL;}

		//IStorage
		virtual HRESULT STDMETHODCALLTYPE CreateStream(const WCHAR *pwcsName, DWORD grfMode, DWORD reserved1, DWORD reserved2, IStream **ppstm){return E_NOTIMPL;}
		virtual HRESULT STDMETHODCALLTYPE OpenStream(const WCHAR * pwcsName, void *reserved1, DWORD grfMode, DWORD reserved2, IStream **ppstm){return E_NOTIMPL;}
		virtual HRESULT STDMETHODCALLTYPE CreateStorage(const WCHAR *pwcsName, DWORD grfMode, DWORD reserved1, DWORD reserved2, IStorage **ppstg){return E_NOTIMPL;}
		virtual HRESULT STDMETHODCALLTYPE OpenStorage(const WCHAR * pwcsName, IStorage * pstgPriority, DWORD grfMode, SNB snbExclude, DWORD reserved, IStorage **ppstg){return E_NOTIMPL;}
		virtual HRESULT STDMETHODCALLTYPE CopyTo(DWORD ciidExclude, IID const *rgiidExclude, SNB snbExclude,IStorage *pstgDest){return E_NOTIMPL;}
		virtual HRESULT STDMETHODCALLTYPE MoveElementTo(const OLECHAR *pwcsName,IStorage * pstgDest, const OLECHAR *pwcsNewName, DWORD grfFlags){return E_NOTIMPL;}
		virtual HRESULT STDMETHODCALLTYPE Commit(DWORD grfCommitFlags){return E_NOTIMPL;}
		virtual HRESULT STDMETHODCALLTYPE Revert(){return E_NOTIMPL;}
		virtual HRESULT STDMETHODCALLTYPE EnumElements(DWORD reserved1, void * reserved2, DWORD reserved3, IEnumSTATSTG ** ppenum){return E_NOTIMPL;}
		virtual HRESULT STDMETHODCALLTYPE DestroyElement(const OLECHAR *pwcsName){return E_NOTIMPL;}
		virtual HRESULT STDMETHODCALLTYPE RenameElement(const WCHAR *pwcsOldName, const WCHAR *pwcsNewName){return E_NOTIMPL;}
		virtual HRESULT STDMETHODCALLTYPE SetElementTimes(const WCHAR *pwcsName, FILETIME const *pctime, FILETIME const *patime, FILETIME const *pmtime){return E_NOTIMPL;}
		virtual HRESULT STDMETHODCALLTYPE SetClass(REFCLSID clsid){return S_OK;}
		virtual HRESULT STDMETHODCALLTYPE SetStateBits(DWORD grfStateBits, DWORD grfMask){return E_NOTIMPL;}
		virtual HRESULT STDMETHODCALLTYPE Stat(STATSTG * pstatstg, DWORD grfStatFlag){return E_NOTIMPL;}

		//IDispatch
		virtual HRESULT STDMETHODCALLTYPE GetTypeInfoCount(UINT *pctinfo){return E_NOTIMPL;}
		virtual HRESULT STDMETHODCALLTYPE GetTypeInfo(UINT iTInfo,LCID lcid,ITypeInfo * *ppTInfo){return E_NOTIMPL;}
		virtual HRESULT STDMETHODCALLTYPE GetIDsOfNames(REFIID riid,LPOLESTR *rgszNames,UINT cNames,LCID lcid,DISPID *rgDispId){return E_NOTIMPL;}
		virtual HRESULT STDMETHODCALLTYPE Invoke(DISPID dispIdMember,REFIID riid,LCID lcid,WORD wFlags,DISPPARAMS *pDispParams,VARIANT *pVarResult,EXCEPINFO *pExcepInfo,UINT *puArgErr);

		//IAdobeShockwaveFlashEvent
		virtual HRESULT STDMETHODCALLTYPE OnReadyStateChange(long newState)
		{
			return S_OK;
		}
		virtual HRESULT STDMETHODCALLTYPE OnProgress(long percentDone)
		{
			return S_OK;
		}
		virtual HRESULT STDMETHODCALLTYPE FSCommand(_bstr_t command, _bstr_t args)
		{
			//OutputDebugString(L"IIIIIIIII");
			if(m_pContainerEvent)
				return m_pContainerEvent->OnFSCommand(command,args);
			return S_OK;
		}
		virtual HRESULT STDMETHODCALLTYPE FlashCall (_bstr_t request ,VARIANT * varResult)
		{

			if(m_pContainerEvent)
				return m_pContainerEvent->OnFlashCall(request,varResult);
			return S_OK;
		}

		
		virtual BOOL releaseSwf(LPCTSTR lpName,LPCTSTR lpType );
		virtual void Draw(const RECT *rcDraw, BOOL bErase);
		virtual HRESULT pushArgument(VARIANT * varArgument);
		virtual HRESULT callFunction(LPCWSTR pFunName,VARIANT * result);
		virtual HRESULT setReturnValue( LPCWSTR lpsz );
		virtual HRESULT setSize(LONG nWidth,LONG nHeight);
		virtual LONG getWidth();
		virtual LONG getHeight();
		virtual HRESULT handleMessage(UINT msg,WPARAM wParam,LPARAM lParam,LRESULT * lResult)
		{
			if(m_spInPlaceObjectWindowless)
			{
				if( msg == WM_NCHITTEST )
				{
					int x = LOWORD(lParam), y = HIWORD(lParam);
					if ( m_spOleObject && m_spViewObjectEx)
					{
						//IViewObjectEx *lpV = m_spViewObjectEx;
						POINT p = {x, y};
						DWORD dwRes;
						RECT rTotal;
						GetWindowRect(m_hWndParent, &rTotal);
						HRESULT hr = m_spViewObjectEx->QueryHitPoint(DVASPECT_CONTENT, &rTotal, p, 1, &dwRes);
						if (hr == S_OK)
						{
							if (dwRes == HITRESULT_OUTSIDE)
								return HTTRANSPARENT;
							else
								return HTCLIENT;
						}
					}
				}
			}
				return m_spInPlaceObjectWindowless->OnWindowMessage(msg,wParam,lParam,lResult);
			return S_OK;
		}
		virtual HRESULT destroy();

		CBFCritSec	m_CSFunCall;
		DWORD		m_dwCurCallThread;
		CCallFlashArgumentEncode m_argEncode;
	public:
		static HRESULT create(LPCWSTR pFixSwfFile,HWND hWndParent,LONG nWidth,LONG nHeight,BFImageHelper::IImageFactory * pImgFactory,IFlashContainerEvent * pEvent,IFlashContainer ** ppFlashContainer);
	};

}
#endif // !defined(AFX_FLASHWND_H__D74EA89B_5D79_4D87_8BB9_4DB90A5FE8FC__INCLUDED_)
